package cn.xyfmzmy.builder;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 通过SqlBuilder来生成sql语句
 */
public class SQL {


    // 1. 查询和修改语句使用不同的Builder，避免使用过程中调用错误的api，如查询时不能调用set()
    // 2. 将build过程分为多个阶段，确保某些api不会重复调用，从api层面隔绝错误


    // ======== SELECT ===========
    public static SelectColumnStage select(){
        return new SelectBuilder();
    }


    interface SelectColumnStage {
        SelectFromStage columns(String ...columns);
    }

    interface SelectFromStage {
        SelectWhereStage from(String table);
    }

    interface SelectWhereStage {
        SelectBuildStage where(String where);
    }

    interface SelectBuildStage {
        String build();
    }


    public static class SelectBuilder implements SelectColumnStage, SelectFromStage, SelectWhereStage, SelectBuildStage{

        private String[] columns;
        private String table;
        private String where;


        @Override
        public SelectFromStage columns(String... columns) {
            this.columns = columns;
            return this;
        }

        @Override
        public SelectWhereStage from(String table) {
            this.table = table;
            return this;
        }

        @Override
        public SelectBuildStage where(String where) {
            this.where = where;
            return this;
        }

        @Override
        public String build(){
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT ").append(String.join(",", columns)).append(" FROM ").append(table);
            if(where != null){
                sql.append(" WHERE ").append(where);
            }
            return sql.toString();
        }

    }



    // ======== UPDATE ===========
    public static UpdateTableStage update(){
        return new UpdateBuilder();
    }

    // 将build过程分为多个阶段，确保某些api不会重复调用，从api层面隔绝错误
    interface UpdateTableStage {
        UpdateSetStage table(String table);
    }

    interface UpdateSetStage {
        UpdateSetStage set(String colum, String value);
        UpdateBuildStage where(String where);
    }

    interface UpdateBuildStage {
        String build();
    }

    public static class UpdateBuilder implements UpdateTableStage, UpdateSetStage, UpdateBuildStage{

        private String table;
        private Map<String,String> setMap = new LinkedHashMap<>();  // 确保遍历时按照插入顺序
        private String where;

        @Override
        public UpdateSetStage table(String table){
            this.table = table;
            return this;
        }

        @Override
        public UpdateSetStage set(String colum, String value){
            setMap.put(colum,value);
            return this;
        }

        @Override
        public UpdateBuildStage where(String where){
            this.where = where;
            return this;
        }

        @Override
        public String build(){
            StringBuilder sql = new StringBuilder();
            sql.append("UPDATE ").append(table).append(" SET ");
            String setString = setMap.entrySet().stream().map(entry -> {
                return entry.getKey() + " = " + entry.getValue();
            }).collect(Collectors.joining(","));
            sql.append(setString);
            sql.append(" WHERE ").append(where);
            return sql.toString();
        }

    }


}
